home *** CD-ROM | disk | FTP | other *** search
- /* $Id: mf.c,v 1.7 89/09/20 17:49:19 mbp Exp $
- *
- * mf.c: metafile procedures
- */
-
- /************************************************************************
- * Copyright (C) 1989 by Mark B. Phillips *
- * *
- * Permission to use, copy, modify, and distribute this software and *
- * its documentation for any purpose and without fee is hereby granted, *
- * provided that the above copyright notice appear in all copies and *
- * that both that copyright notice and this permission notice appear in *
- * supporting documentation, and that the name of Mark B. Phillips or *
- * the University of Maryland not be used in advertising or publicity *
- * pertaining to distribution of the software without specific, written *
- * prior permission. This software is provided "as is" without express *
- * or implied warranty. *
- ************************************************************************/
-
- #include <stdio.h>
- #include "lgd.h"
- #include "internal.h"
- #include "mf.h"
-
- /************************************************************************
- * PUBLIC DEFINITIONS *
- ************************************************************************/
-
- /* Maximum value of data stored in MF: */
- mfe MF_max_val;
-
- /* Metafile commands: */
- mfe MF_begin_segment;
- mfe MF_end_segment;
- mfe MF_pen_up;
- mfe MF_pen_down;
- mfe MF_point;
- mfe MF_line_style;
- mfe MF_color;
-
- /* Largest command value: */
- mfe MF_max_command;
-
- /* Global metafile error flag */
- char *mf_error=NULL;
-
- /* Length of metafile (number of words): */
- #define MF_LENGTH 50000
-
- /* The metafile itself: */
- mfe mf_metafile[MF_LENGTH];
-
- /*--------------------End of Public Definitions-------------------------*/
-
- /************************************************************************
- * PRIVATE DEFINITIONS *
- ************************************************************************/
-
- /* Address of first entry in MF: */
- static mfa mf_start;
-
- /* Address of last entry in MF (mf_end=0 means empty MF): */
- static mfa mf_end;
-
- /* NOTE: The above defs mean that at any given time, the MF contains
- * mf_end-mf_start+1 words at addresses mf_start through and including
- * mf_end */
-
- /*--------------------End of Private Definitions------------------------*/
-
- /************************************************************************
- * PUBLIC PROCEDURES *
- ************************************************************************/
-
- /*-----------------------------------------------------------------------
- * Function: mf_initialize
- * Description: Initialize the MetaFile
- * Arguments: (none)
- * Returns: nothing
- */
- mf_initialize()
- {
- mf_start = 1;
- mf_end = 0;
- MF_max_val = 65500;
- MF_begin_segment = MF_max_val+1;
- MF_end_segment = MF_max_val+2;
- MF_pen_up = MF_max_val+3;
- MF_pen_down = MF_max_val+4;
- MF_point = MF_max_val+5;
- MF_line_style = MF_max_val+6;
- MF_color = MF_max_val+7;
- MF_max_command = MF_max_val+7;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_save
- * Description: Write MetaFile to a disk file
- * Arguments IN: fp: file to write to
- * Returns: nothing
- * Notes: fp should point to a file which has been opened
- * for binary writing.
- */
- mf_save( fp )
- FILE *fp;
- {
- mfa first,last,address,length;
- mfe entry;
- int items_written;
-
- /*
- *********************
- * THIS IS FORMAT 3 *
- *********************
- */
- first = mf_first_addr();
- last = mf_last_addr();
- length = last - first + 1;
- items_written = /* Write length */
- fwrite( (char*)&length, sizeof(mfa), 1, fp );
- if (items_written!=1) {
- mf_error = E_sm_bad_write;
- return;
- }
- /* Write metafile: */
- for (address=first; address<=last; ++address) {
- entry = mf_peek(address);
- items_written = fwrite( (char*)&entry,
- sizeof(mfe),1,fp );
- if (items_written!=1) {
- mf_error = E_sm_bad_write;
- return;
- }
- }
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_load
- * Description: Read a MetaFile from a disk file
- * Arguments IN: fp: file to write to
- * Returns: nothing
- * Notes: fp should point to a file which has been opened
- * for binary reading
- */
- mf_load( fp )
- FILE *fp;
- {
- mfe entry;
- mfa length;
- int items_read;
-
- /*
- *********************
- * THIS IS FORMAT 3 *
- *********************
- */
- mf_initialize();
- items_read = /* Read length */
- fread( (char*)&length,sizeof(mfa), 1, fp);
- if (items_read!=1) {
- mf_error = E_sm_bad_write;
- return;
- }
- /* Read metafile: */
- while ( (length>0) && (mf_error==NULL) ) {
- items_read = fread((char*)&entry, sizeof(mfe), 1, fp );
- if (items_read!=1) {
- mf_error = E_sm_bad_write;
- return;
- }
- mf_append( entry );
- --length;
- }
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_first_addr
- * Description: Get the address of the first entry in the MF
- * Arguments: (none)
- * Returns: The address of the first entry
- */
- mfa mf_first_addr()
- {
- return( mf_start );
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_last_addr
- * Description: Get the address of the last entry in the MF
- * Arguments: (none)
- * Returns: The address of the last entry
- * Notes: This is the last actually used entry -- not the
- * last theoretical position in the MF.
- */
- mfa mf_last_addr()
- {
- return( mf_end );
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_poke
- * Description: Store an entry in the MF
- * Arguments IN: address: address to write to
- * value: value to write at address
- * Returns: nothing
- */
- mf_poke( address, value )
- mfa address;
- mfe value;
- {
- mf_metafile[address] = value;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_append
- * Description: Append an entry to end of MF
- * Arguments IN: value: value to append
- * Returns: nothing
- * Notes: Sets an error if there is no more room in MF
- */
- mf_append( value )
- mfe value;
- {
- if (MF_LENGTH-mf_end<1) {
- mf_error = E_mf_overflow;
- return;
- }
- mf_poke( ++mf_end, value );
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_append_array
- * Description: Append an array of entries to end of MF
- * Arguments IN: value_array: array to append
- * n: length of (number of entries in) value array
- * Returns: nothing
- * Notes: Sets an error if there is not enough room in MF
- */
- mf_append_array( value_array, n )
- mfe value_array[];
- int n;
- {
- if (MF_LENGTH-mf_end<n) {
- mf_error = E_mf_overflow;
- return;
- }
- while (n) {
- mf_poke( ++mf_end, *value_array );
- ++value_array;
- --n;
- }
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_truncate
- * Description: Truncate MF at a given point
- * Arguments IN: address: address to truncate at
- * Returns: nothing
- * Notes: After truncation, address is the address of the
- * last entry in MF. If address is out of range,
- * an error is set.
- */
- mf_truncate( address )
- mfa address;
- {
- if ( (address<mf_start-1)
- || (address>MF_LENGTH ) ) {
- mf_error = E_bad_trunc;
- return;
- }
- mf_end = address;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_compress
- * Description: Compress out a region of the MF
- * Arguments IN: first: first address of region to take out
- * last: last address of region to take out
- * Returns: nothing
- * Notes: The region compressed out is first thru last, inclusive.
- * If first or last is out of range, an error is set.
- */
- mf_compress( first, last )
- register mfa first;
- register mfa last;
- {
- if ( (first<mf_start)
- || (last>mf_end)
- || (first>last) ) {
- mf_error = E_bad_compress;
- return;
- }
- while (last<mf_end) {
- ++last;
- mf_metafile[first] = mf_metafile[last];
- ++first;
- }
- mf_end = first - 1;
- }
-
- /*-----------------------------------------------------------------------
- * Function: mf_length
- * Description: Get the total potential length of the MetaFile
- * Arguments: (none)
- * Returns: the number of entry positions
- * Notes: This is the maximum possible length; not just the
- * currently used part.
- */
- mfa
- mf_length()
- {
- return( (mfa) MF_LENGTH );
- }
-
- /*---------------------End of Public Procedures-------------------------*/
-